package servlet;

import com.octo.captcha.service.CaptchaServiceException;
import entity.Book;
import entity.EntityManagerHelper;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;
import util.CaptchaServiceSingleton;
import util.Utilities;

/**
 *
 * @author Administrator
 */
public class FileUploadTest2 extends HttpServlet {

    private final Calendar cal = new GregorianCalendar();
    private String uploadPath = null;
    private final String tempPath = "c:\\temp\\buffer\\";

    @Override
    public void init() throws ServletException {
        super.init();
        uploadPath = this.getServletContext().getRealPath("items");
        
        File uploadFile = new File(uploadPath);
        if (!uploadFile.exists()) {
            uploadFile.mkdirs();
        }
        File tempPathFile = new File(tempPath);
        if (!tempPathFile.exists()) {
            tempPathFile.mkdirs();
        }
    }

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //web parameters
        String bookName = null;
        String volume = null;
        String year = null;
        String edition = null;
        String author = null;
        String publisher = null;
        String description = null;
        String price = null;
        String quantity = null;
        String location = null;
        String image1 = null;
        String image2 = null;
        String image3 = null;
        String tags = null;
        String tag1 = null;
        String tag2 = null;
        String tag3 = null;
        String condition = null;
        String minRating = null;
        String captchaCode = null;

        //path
        File savedFile = null;
        File tempPathFile = new File(tempPath);

        //tenp variables
        String fieldName = null;
        String fieldValue = null;
        String fileName = null;
        String contentType = null;

        try {
            // Create a factory for disk-based file items
            DiskFileItemFactory factory = new DiskFileItemFactory();

            // Set factory constraints
            factory.setSizeThreshold(10 * 1024 * 1024); // 10MB buffer
            factory.setRepository(tempPathFile);// buffer dir

            // Create a new file upload handler
            ServletFileUpload upload = new ServletFileUpload(factory);

            // Set overall request size constraint
            upload.setSizeMax(512 * 1024); // max file size 5kB

            List<FileItem> fileItems = null;
            try {
                fileItems = (List<FileItem>) upload.parseRequest(request);//it will throw exception of some of the file excede the limit
            } catch (Exception e) {
            }
            Iterator<FileItem> fileIterator = fileItems.iterator();
            while (fileIterator.hasNext()) {
                FileItem item = fileIterator.next();
                fieldName = item.getFieldName();
                if (item.isFormField()) { //read in all the parameter
                    fieldValue = item.getString();
                    if ("bookname".equals(fieldName)) {
                        bookName = fieldValue;
                    } else if ("volume".equals(fieldName)) {
                        volume = fieldValue;
                    } else if ("year".equals(fieldName)) {
                        year = fieldValue;
                    } else if ("edition".equals(fieldName)) {
                        edition = fieldValue;
                    } else if ("author".equals(fieldName)) {
                        author = fieldValue;
                    } else if ("publisher".equals(fieldName)) {
                        publisher = fieldValue;
                    } else if ("itemDescription".equals(fieldName)) {
                        description = fieldValue;
                    } else if ("price".equals(fieldName)) {
                        price = fieldValue;
                    } else if ("quantity".equals(fieldName)) {
                        quantity = fieldValue;
                    } else if ("tradeLocation".equals(fieldName)) {
                        location = fieldValue;
                    } else if ("tags".equals(fieldName)) {
                        tags = fieldValue;
                        String[] tagTokens = tags.split(",");
                        if (tagTokens.length > 0) {
                            tag1 = tagTokens[0].trim();
                        }
                        if (tagTokens.length > 1) {
                            tag2 = tagTokens[1].trim();
                        }
                        if (tagTokens.length > 2) {
                            tag3 = tagTokens[2].trim();
                        }
                    } else if ("itemCondition".equals(fieldName)) {
                        condition = fieldValue;
                    } else if ("minRating".equals(fieldName)) {
                        minRating = fieldValue;
                    } else if ("bookcaptchacode".equals(fieldName)) {
                        captchaCode = fieldValue;
                    }
                } else {//upload the file
                    fileName = item.getName();
                    contentType = item.getContentType();
                    //todo: check content type
                    //todo: rename
                    if (!"".equals(fileName)) {    // if user have select a file      
                        fileName = FilenameUtils.getName(fileName);
                        if ("image1".equals(fieldName)) {
                            image1 = fileName;
                        } else if ("image2".equals(fieldName)) {
                            image2 = fileName;
                        } else if ("image3".equals(fieldName)) {
                            image3 = fileName;
                        }
                        savedFile = new File(uploadPath, fileName);
                        item.write(savedFile);
                    }
                }
            }
        } catch (Exception e) {
            //response.sendRedirect("AddItem.jsp?panel=sBookPanel&msg=invalid_file_size");
            return;
        }

        // Temporarily store the data that user input to the form
        // actually it is not temporarily.... these values have to be deleted form the session manually
        HttpSession session = request.getSession(true);
        session.setAttribute("bookName", bookName);
        session.setAttribute("volume", volume);
        session.setAttribute("year", year);
        session.setAttribute("edition", edition);
        session.setAttribute("author", author);
        session.setAttribute("publisher", publisher);
        session.setAttribute("itemDescription", description);
        session.setAttribute("price", price);
        session.setAttribute("quantity", quantity);
        session.setAttribute("location", location);
        session.setAttribute("image1", image1);
        session.setAttribute("image2", image2);
        session.setAttribute("image3", image3);
        session.setAttribute("tags", tags);
        session.setAttribute("condition", condition);
        session.setAttribute("minRating", minRating);
        session.setAttribute("image1", image1);
        session.setAttribute("image2", image2);
        session.setAttribute("image3", image3);

        //convert to UTF-8 for internal processing
        bookName = Utilities.toUTF8(bookName);
        author = Utilities.toUTF8(author);
        publisher = Utilities.toUTF8(publisher);
        description = Utilities.toUTF8(description);
        location = Utilities.toUTF8(location);
        tags = Utilities.toUTF8(tags);

        //todo: use personID instead, if possible
        //String personID = (String) session.getAttribute("personID");
        int personID = 1;

        //check the necessary fields FIRST
        if (bookName.isEmpty() || price.isEmpty() || quantity.isEmpty() || tags.isEmpty() || condition.isEmpty() || minRating.isEmpty()) {
            response.sendRedirect("AddItem.jsp?panel=sBookPanel&msg=necessary_empty_error");
            return;
        }

        // Check for valid Captcha code entered by user
        try {
            boolean isCorrectCaptcha = false;
            isCorrectCaptcha = CaptchaServiceSingleton.getInstance().validateResponseForID(session.getId(), captchaCode);
            if (!isCorrectCaptcha) {
                response.sendRedirect("AddItem.jsp?panel=sBookPanel&msg=cap_error");
                return;
            }
        } catch (CaptchaServiceException e) {
            //should not happen, may be thrown if the id is not valid
        }

        //********************* Year  *******************
        int yearInt = 0;
        if (!year.isEmpty()) {  //check if user enter the value
            try {
                yearInt = Integer.parseInt(year);
            } catch (Exception e) {
                response.sendRedirect("AddItem.jsp?panel=sBookPanel&msg=year_error");
                return;
            }
            int yearCurrent = cal.get(Calendar.YEAR);
            if (yearInt < yearCurrent - 200 || yearInt > yearCurrent) {
                response.sendRedirect("AddItem.jsp?panel=sBookPanel&msg=year_error");
                return;
            }
        }


        //********************* Edition *******************
        int editionInt = 0;
        if (!edition.isEmpty()) {  //check if user enter the value
            try {
                editionInt = Integer.parseInt(edition);
            } catch (Exception e) {
                response.sendRedirect("AddItem.jsp?panel=sBookPanel&msg=edition_error");
                return;
            }
            if (editionInt < 0) {
                response.sendRedirect("AddItem.jsp?panel=sBookPanel&msg=edition_error");
                return;
            }
        }

        //********************* Price *********************
        double priceDouble = 0;
        try {
            priceDouble = NumberFormat.getCurrencyInstance(Locale.US).parse("$" + price).doubleValue();
        } catch (Exception e) {
            response.sendRedirect("AddItem.jsp?panel=sBookPanel&msg=money_error");
            return;
        }

        //********************* Quantity ******************
        int quantityInt = 0;
        try {
            quantityInt = Integer.parseInt(quantity);
        } catch (Exception e) {
            response.sendRedirect("AddItem.jsp?panel=sBookPanel&msg=quantity_error");
            return;
        }
        if (quantityInt <= 0) {
            response.sendRedirect("AddItem.jsp?panel=sBookPanel&msg=quantity_error");
            return;
        }
        //********************* Condition ****************
        int conditionInt = 0;
        //if(!condition.isEmpty()){  //not optional field
        try {
            conditionInt = Integer.parseInt(condition);
        } catch (Exception e) {
            response.sendRedirect("AddItem.jsp?panel=sBookPanel&msg=condition_error");
            return;
        }
        if (conditionInt < 0) {
            response.sendRedirect("AddItem.jsp?panel=sBookPanel&msg=condition_error");
        }
        //}
        //********************* Min Rating ****************
        int minRatingInt = 0;
        //if(!condition.isEmpty()){  //not optional field
        try {
            minRatingInt = Integer.parseInt(minRating);
        } catch (Exception e) {
            response.sendRedirect("AddItem.jsp?panel=sBookPanel&msg=minRating_error");
            return;
        }
        //}


        //create a DB entity
        Book book = new Book();

       // book.setAuthor(author);
        book.setDescription(description);
      //  book.setEdition(editionInt);
        book.setLocation(location);
        book.setName(bookName);
        book.setPrice(new BigDecimal(priceDouble));
       // book.setPublisher(publisher);
        book.setQuantity(quantityInt);
        book.setStatusCode(0);
       // book.setVolume(volume);
       // book.setYear(yearInt);
        book.setPersonID(personID);
        book.setAddDate(Utilities.now());
        book.setCondition(conditionInt);
        book.setTag1(tag1);
        book.setTag2(tag2);
        book.setTag3(tag3);
        book.setImage1(image1);
        book.setImage2(image2);
        book.setImage3(image3);

        //todo:book.setMinRating(minRatingInt);
        //todo:set number of time of renew        

        //store into the db
        boolean result = EntityManagerHelper.persist(book, EntityManagerHelper.getFactory());



    }
    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /** 
     * Returns a short description of the servlet.
     */
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
